package bridge;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.sun.org.apache.regexp.internal.RE;
import com.sun.org.apache.regexp.internal.RESyntaxException;

/**
 * @author bajo
 */

public class TableGenerator {
	public final static int NR_OF_TEAMS_IN_LEAGUE = 16; 
	public final static String RESULTS_FILE_NAME = "c://eclipse//workspace//bridge2//WebContent//LO2011.xml";
	//workspace\bridge2\WebContent
	static BufferedReader input;
	List<Team> teams = new ArrayList(NR_OF_TEAMS_IN_LEAGUE);

    public TableGenerator() {
    }

	public static void main(String[] args) {
		TableGenerator tableGenerator = new TableGenerator();
		tableGenerator.openFiles(RESULTS_FILE_NAME);
		tableGenerator.getTeamResultsFromXML();
		tableGenerator.generateTable();
		tableGenerator.printTable();		
		tableGenerator.closeFiles();
	}
	
	/**
	 * 
	 */
	public void printTable() {
		Iterator teamsIt = teams.iterator();
		while (teamsIt.hasNext()) {
			Team team = (Team) teamsIt.next();
			System.out.println("---"+team.toString()+"---");
		}
	}

	/**
	 * 
	 */
	public void getTeamResults() {
		String line;		
		try {
			while ((line = input.readLine()) != null) {
				if (teamLineOK().match(line)) {
					String[] team = lineSpliter().split(line);
					Team newTeam = new Team(team[0], team[1]);
					int newTeamResults[] = new int[TableGenerator.NR_OF_TEAMS_IN_LEAGUE];
					for (int i = 0; i < newTeamResults.length; i++) {
						newTeamResults[i] = (int)Double.parseDouble(team[i+2].trim());
					}
					newTeam.setResults(newTeamResults);
					System.out.println("jestem!2!!");	
					teams.add(newTeam);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void getTeamResultsFromXML() {
		int newTeamResults[][] = new int[NR_OF_TEAMS_IN_LEAGUE][NR_OF_TEAMS_IN_LEAGUE];
		for(int i=0; i<NR_OF_TEAMS_IN_LEAGUE; i++) {
			for(int j=0; j<NR_OF_TEAMS_IN_LEAGUE; j++) {
				if(i==j) { 
					newTeamResults[i][j] = -8;
				} else {
					newTeamResults[i][j] = -1;
				}
			}
		}
		Map zespoly = new HashMap();
		try {
			  File file = new File(RESULTS_FILE_NAME);
			  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			  DocumentBuilder db = dbf.newDocumentBuilder();
			  Document doc = db.parse(file);
			  doc.getDocumentElement().normalize();
			  System.out.println("Root element " + doc.getDocumentElement().getNodeName());
			  NodeList nodeLst = doc.getElementsByTagName("tr");
		
			  for (int s = 0; s < NR_OF_TEAMS_IN_LEAGUE; s++) {
		
			    Node fstNode = nodeLst.item(s);
			    
			    if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
			  
			      Element elmnt = (Element) fstNode;
			      
			      NodeList miejsceElmntLst = elmnt.getElementsByTagName("td");
			      Element miejsceElmnt = (Element) miejsceElmntLst.item(0);
			      NodeList miejsce = miejsceElmnt.getChildNodes();
			      String miejsceVal = ((Node) miejsce.item(0)).getNodeValue();
				System.out.println("Miejsce : "  + miejsceVal);
			      
			      NodeList nazwaElmntLst = elmnt.getElementsByTagName("td");
			      Element nazwaElmnt = (Element) nazwaElmntLst.item(1);
			      NodeList nazwa = nazwaElmnt.getChildNodes();
			      String nazwaVal = ((Node) nazwa.item(0)).getNodeValue();
				System.out.println("Last Name : " + nazwaVal);

			      NodeList punktyElmntLst = elmnt.getElementsByTagName("td");
			      Element punktyElmnt = (Element) punktyElmntLst.item(2);
			      NodeList punkty = punktyElmnt.getChildNodes();
			      String punktyVal = ((Node) punkty.item(0)).getNodeValue();
				System.out.println("Punkty : " + punktyVal);

			      teams.add(Integer.parseInt(miejsceVal.trim())-1, new Team(miejsceVal, nazwaVal));
			      zespoly.put(nazwaVal, miejsceVal);
			    }
			  }
			  for (int s = NR_OF_TEAMS_IN_LEAGUE; s < nodeLst.getLength(); s++) {
				  Node fstNode = nodeLst.item(s);
				  if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
					  Element elmnt = (Element) fstNode;
				      
				      NodeList gospodarzElmntLst = elmnt.getElementsByTagName("td");
				      Element gospodarzElmnt = (Element) gospodarzElmntLst.item(0);
				      NodeList gospodarz = gospodarzElmnt.getChildNodes();
				      String gospodarzVal = ((Node) gospodarz.item(0)).getNodeValue();
				      
				      NodeList goscElmntLst = elmnt.getElementsByTagName("td");
				      Element goscElmnt = (Element) goscElmntLst.item(2);
				      NodeList gosc = goscElmnt.getChildNodes();
				      String goscVal = ((Node) gosc.item(0)).getNodeValue();
				      
				      NodeList wynikLst = elmnt.getElementsByTagName("td");
				      Element wynikElmnt = (Element) wynikLst.item(4);
				      NodeList wynik = wynikElmnt.getElementsByTagName("b");
				      Element wynikRealElmnt = (Element) wynik.item(0);
				      NodeList wynikOst = wynikRealElmnt.getChildNodes();
				      String wynikVal = ((Node) wynikOst.item(0)).getNodeValue();
				      
				      int miejscePodzialuWyniku = wynikVal.indexOf(":");
				      int wynikGospodzarz = (int)Double.parseDouble(wynikVal.substring(0, miejscePodzialuWyniku));
				      int wynikGosc = (int)Double.parseDouble(wynikVal.substring(miejscePodzialuWyniku+1));
				      int gospodarzId = Integer.parseInt(((String) zespoly.get(gospodarzVal)).trim())-1;
				      int goscId = Integer.parseInt(((String) zespoly.get(goscVal)).trim())-1;
				      newTeamResults[gospodarzId][goscId] = wynikGospodzarz;
				      newTeamResults[goscId][gospodarzId] = wynikGosc;
				  }
			  }
		  } catch (Exception e) {
			  e.printStackTrace();
		  }
		for (int s = 0; s < NR_OF_TEAMS_IN_LEAGUE; s++) {
			Team team = (Team) teams.get(s);
			team.setResults(newTeamResults[s]);
		}
		for (int s = 0; s < NR_OF_TEAMS_IN_LEAGUE; s++) {
			double odchylenie = policzOdchylenie(s, teams);
			Team team = (Team) teams.get(s);
			team.setOdchylenie(new BigDecimal(odchylenie).setScale(2, 2));
		}
	 }

	private double policzOdchylenie(int s, List<Team> teams) {
		int liczbaMeczy = 0;
		double odchylenie = 0.0;
		Team team = (Team)teams.get(s);
		for (int i = 0; i < team.getResults().length; i++) {
			int wynikZPrzeciwnikiem = team.getResultInt(i);
			if (wynikZPrzeciwnikiem >= 0) {
				liczbaMeczy++;
				Team teamMecz = (Team)teams.get(i);
				BigDecimal sredniWynikPrzeciwnikow = teamMecz.getSrednia();
				odchylenie += (double)wynikZPrzeciwnikiem -(30-sredniWynikPrzeciwnikow.doubleValue());
			}
		}
		odchylenie = odchylenie/liczbaMeczy;
		return odchylenie;
	}

	public void closeFiles() {
		try {
			input.close();
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		
	}

	public void generateTable() {
		Collections.sort(teams, new TeamComparator());
	}


	public void openFiles(String filename) {
		try {
			System.out.println("otwieram");			
			input = new BufferedReader(new InputStreamReader(new FileInputStream(filename), Charset.forName("UTF-8")));
			System.out.println("otwarte");
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();
		}		
	}


	public static RE teamLineOK() {

			RE format = null;

			try {
				// there are 13 fields that can be passed into this expression
				// all mathed string has to be all line long (^ ... $)
				// one token is everything except ";" [^;]* plus ;
				format = new RE("^[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;[^;]*;[^;]*$");
			} catch (RESyntaxException rese) {
				rese.printStackTrace();
			}        
        
			return format;
		}
	
	/**
	 * @return
	 */
	public static RE lineSpliter() {

		RE format = null;

		try {
			format = new RE(";");
		} catch (RESyntaxException rese) {
			rese.printStackTrace();
		}        
        
		return format;
	}	

	/**
	 * @return
	 */
	public List getTeams() {
		return teams;
	}

}
